﻿using Nx.Commands;
using Nx.UI.Navigation;
using Nx.ViewModels;
using System;
#if SILVERLIGHT && !WINDOWS_PHONE
using System.Windows.Navigation;
#endif

namespace Nx.Modules
{
    public abstract class NavigationLink
    {
#if !NETFX_CORE
        public NavigationLink(string title, Uri targetPage, Uri imageSource, int index)
#else
        public NavigationLink(string title, Type targetViewType, Uri imageSource, int index)
#endif
        {
            this.Title = title;
#if!NETFX_CORE
            this.NavigationTarget = new NavigationTarget(targetPage);
#else
            this.NavigationTarget = new NavigationTarget(targetViewType);
#endif
            this.ImageSource = imageSource;
            this.Index = index;

#if SILVERLIGHT && !WINDOWS_PHONE
            this.UriMapping = new UriMapping()
            {
                Uri = targetPage,
                MappedUri = targetPage
            };
#endif
        }

#if !NETFX_CORE
        public NavigationLink(string title, string subtitle, Uri targetPage, Uri imageSource, int index)
            : this(title, targetPage, imageSource, index)
#else
        public NavigationLink(string title, string subtitle, Type targetViewType, Uri imageSource, int index)
            : this(title, targetViewType, imageSource, index)
#endif
        {
            SubTitle = subtitle;
        }

#if SILVERLIGHT && !WINDOWS_PHONE
        public UriMapping UriMapping { get; private set; }
#endif

        public string Title { get; private set; }
        public string SubTitle { get; private set; }

        public INavigationTarget NavigationTarget { get; private set; }
        //#if!NETFX_CORE
        //        public Uri TargetPage { get; private set; }
        //#else
        //        public Type TargetViewType { get; private set; }
        //#endif

        public Uri ImageSource { get; private set; }
        public int Index { get; private set; }
    }

    public class NavigationLink<TNavEnum> : NavigationLink
    {
#if !NETFX_CORE
        public NavigationLink(TNavEnum type, string title, Uri targetPage, Uri imageSource, int index)
            : base(title, targetPage, imageSource, index)
#else
        public NavigationLink(TNavEnum type, string title, Type targetViewType, Uri imageSource, int index)
            : base(title, targetViewType, imageSource, index)
#endif
        {
            this.Type = type;
        }

#if !NETFX_CORE
        public NavigationLink(TNavEnum type, string title, string subtitle, Uri targetPage, Uri imageSource, int index)
            : base(title, subtitle, targetPage, imageSource, index)
#else
        public NavigationLink(TNavEnum type, string title, string subtitle, Type targetViewType, Uri imageSource, int index)
            : base(title, subtitle, targetViewType, imageSource, index)
#endif
        {
            this.Type = type;
        }

        public TNavEnum Type { get; private set; }
    }

    public sealed class NavigationLink<TNavEnum, TViewModel> : NavigationLink<TNavEnum>
        where TViewModel : ViewModelBase
    {
#if !NETFX_CORE
        private NavigationLink(TNavEnum type, string title, Uri targetPage, Uri imageSource, int index)
            : base(type, title, targetPage, imageSource, index)
#else
        private NavigationLink(TNavEnum type, string title, Type targetViewType, Uri imageSource, int index)
            : base(type, title, targetViewType, imageSource, index)
#endif
        {
            this.ViewModelType = typeof(TViewModel);
        }

#if !NETFX_CORE
        public NavigationLink(TNavEnum type, INavigationModel<TNavEnum> navigationModel, string title, Uri targetPage, Uri imageSource, int index)
            : this(type, title, targetPage, imageSource, index)
#else
        public NavigationLink(TNavEnum type, INavigationModel<TNavEnum> navigationModel, string title, Type targetViewType, Uri imageSource, int index)
            : this(type, title, targetViewType, imageSource, index)
#endif
        {
            this.NavigationModel = navigationModel;
        }

#if !NETFX_CORE
        private NavigationLink(TNavEnum type, string title, string subtitle, Uri targetPage, Uri imageSource, int index)
            : base(type, title, subtitle, targetPage, imageSource, index)
#else
        private NavigationLink(TNavEnum type, string title, string subtitle, Type targetViewType, Uri imageSource, int index)
            : base(type, title, subtitle, targetViewType, imageSource, index)
#endif
        {
            this.ViewModelType = typeof(TViewModel);
        }

#if !NETFX_CORE
        public NavigationLink(TNavEnum type, INavigationModel<TNavEnum> navigationModel, string title, string subtitle, Uri targetPage, Uri imageSource, int index)
            : this(type, title, subtitle, targetPage, imageSource, index)
#else
        public NavigationLink(TNavEnum type, INavigationModel<TNavEnum> navigationModel, string title, string subtitle, Type targetViewType, Uri imageSource, int index)
            : this(type, title, subtitle, targetViewType, imageSource, index)
#endif
        {
            this.NavigationModel = navigationModel;
        }

        public Type ViewModelType { get; private set; }
        public INavigationModel<TNavEnum> NavigationModel { get; private set; }

        private Command<object> _NavigateCommand;
        public Command<object> NavigateCommand
        {
            get
            {
                if (_NavigateCommand == null)
                {
                    _NavigateCommand = new Command<object>(OnNavigate);
                }

                return _NavigateCommand;
            }
        }

        private void OnNavigate(object o)
        {
            this.NavigationModel.NavigateTo(this.Type);
        }
    }
}
